package com.example.demon.jwt.filters;

import com.example.demon.service.UserDetailService;
import com.example.demon.jwt.handler.CustomAuthenticationFailureHandler;
import com.example.demon.utils.JwtTokenUtil;
import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;

@Component
public class JwtAuthenticationFilter extends OncePerRequestFilter {
    @Autowired
    JwtTokenUtil jwtTokenUtil;
    @Autowired
    UserDetailService userDetailService;
    @Autowired
    CustomAuthenticationFailureHandler customAuthenticationFailureHandler;


    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        System.out.println("进入JwtAuthenticationFilter");
        String jwtToken = request.getHeader(JwtTokenUtil.TOKEN_HEADER);

        try {
            if (!StringUtils.isEmpty(jwtToken) && !jwtTokenUtil.isTokenExpired(jwtToken)) {
                String username = jwtTokenUtil.getUsernameFromToken(jwtToken);
                if (!StringUtils.isEmpty(username) && SecurityContextHolder.getContext().getAuthentication() == null) {
                    UserDetails userDetails = userDetailService.loadUserByUsername(username);
                    UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
                    SecurityContextHolder.getContext().setAuthentication(authenticationToken);
                } else if (username == null) {
                    throw new BadCredentialsException("token解析错误，请重新登录");
                }
            }
        }catch (AuthenticationException e){
            customAuthenticationFailureHandler.onAuthenticationFailure(
                    request,response,e
            );
            return;
        }

        filterChain.doFilter(request, response);
    }
}